#include "CM.h"
#include "Type_Define.h"
#include "IO_LINK_Global_Param.h"
#include "SMI.h"
#include "Phy_Driver.h"
#include "SM.h"
#include "DS.h"

/********************
     暂时排除在工程外 8.3

****************/

CM_STATE_TYPE CM_STATE[PORT_NUM];
 

void CM_Init(void){
    for(uint8_t i=0;i<PORT_NUM;i++){
        CM_STATE[i]=CM_CheckPortMode_0;
        //从Flash中读取DS Object 参数（VendorID DeviceID）
       // Read_Data_From_FlashROM(SMI_PortConfigList_FlashAddress(i),(void *)&SMI_PortConfigList[i],sizeof(PortConfigList_TYPE));
        Action_do_ModeCheck(i);//检查DS里保存的ConfigList情况
    }
    
   

}






/*******************转移函数*************/

void CM_T1(uint8_t Port){
  //从DS中读取DS header信息
  DS_Object_Header_TYPE DS_Header;
 
  Read_Data_From_FlashROM(DS_Header_FlashAddress(Port),(void *)&DS_Header,12);
  uint16_t VenderID=DS_Header.VendorID;
  uint32_t DeviceID=DS_Header.DeviceID;
   //DS_中保存的VendorID DeviceID与SMI配置的不同
   
   if(SMI_PortConfigList[Port].VendorID!= VendorID||SMI_PortConfigList[Port].DeviceID!= DeviceID){
         Event_DS_Delete(Port);     
         
   } 

   SM_SetPortConfig_Arg_TYPE SM_Arg;
    //解析SMI的ConfigList,得到SM_SetConfig部分参数
    Parase_PortConfigList(Port,&SM_Arg,&SMI_PortConfigList[Port]);
     
   
    //调用SM_SetPortConfig服务
    Service_SM_SetPortConfig_req(SM_Arg);

}

void CM_T2(uint8_t Port){
    Event_DS_Delete(Port);   
     SM_SetPortConfig_Arg_TYPE SM_Arg;
    //解析SMI的ConfigList,得到SM_SetConfig部分参数
    Parase_PortConfigList(Port,&SM_Arg,&SMI_PortConfigList[Port]);
     
    //CM转换状态
    CM_STATE[Port]=CM_SM_Startup_1;
    //调用SM_SetPortConfig服务
    Service_SM_SetPortConfig_req(SM_Arg);

}

void CM_T3(uint8_t Port){
    

    Event_DS_Startup(Port);
     
    ////////////
   PortStatusList_TYPE * SMI_PortStatusList=(PortStatusList_TYPE *)malloc(sizeof(PortStatusList_TYPE));

    SMI_PortStatusList->ArgBlockID=0x9000;
    SMI_PortStatusList->PortStatusInfo=0x03; //PREOPERATE
    SMI_PortStatusList->PortQualityInfo=0x01;// invalid
    SMI_PortStatusList->RevisionID=RevisionID[Port]; //RevisionID
    SMI_PortStatusList->TransmissionRete=SM_COM_Speed[Port]; //Transmission rate
    SMI_PortStatusList->VendorID=VendorID;
    SMI_PortStatusList->DeviceID=DeviceID;
    SMI_PortStatusList->MasterCycleTime=CfgCycleTime[Port];
     
    Insert_SMI_Object_To_Result_FIFO(0x0000,Port,sizeof(SMI_PortStatusList[Port]),(void *)&SMI_PortStatusList[Port]);

}

void CM_T4(uint8_t Port){
      PortStatusList_TYPE * SMI_PortStatusList=(PortStatusList_TYPE *)malloc(sizeof(PortStatusList_TYPE));

    SMI_PortStatusList->ArgBlockID=0x9000;
    SMI_PortStatusList->PortStatusInfo=0x02; //PORT_DIAG
    SMI_PortStatusList->PortQualityInfo=0x01;// invalid
    SMI_PortStatusList->RevisionID=RevisionID[Port]; //RevisionID
    SMI_PortStatusList->TransmissionRete=SM_COM_Speed[Port]; //Transmission rate
    SMI_PortStatusList->VendorID=VendorID;
    SMI_PortStatusList->DeviceID=DeviceID;
    SMI_PortStatusList->MasterCycleTime=CfgCycleTime[Port];
     
    Insert_SMI_Object_To_Result_FIFO(0x0000,Port,sizeof(SMI_PortStatusList[Port]),(void *)&SMI_PortStatusList[Port]);

}


void CM_T5(uint8_t Port){
    Service_SM_Operate_req(Port);
}

void CM_T6(uint8_t Port){
    PortStatusList_TYPE * SMI_PortStatusList=(PortStatusList_TYPE *)malloc(sizeof(PortStatusList_TYPE));

    SMI_PortStatusList->ArgBlockID=0x9000;
    SMI_PortStatusList->PortStatusInfo=0x02; //PORT_DIAG
    SMI_PortStatusList->PortQualityInfo=0x01;// invalid
    SMI_PortStatusList->RevisionID=RevisionID[Port]; //RevisionID
    SMI_PortStatusList->TransmissionRete=SM_COM_Speed[Port]; //Transmission rate
    SMI_PortStatusList->VendorID=VendorID;
    SMI_PortStatusList->DeviceID=DeviceID;
    SMI_PortStatusList->MasterCycleTime=CfgCycleTime[Port];
     
    Insert_SMI_Object_To_Result_FIFO(0x0000,Port,sizeof(SMI_PortStatusList[Port]),(void *)&SMI_PortStatusList[Port]);

}

void CM_T7(uint8_t Port){
   PortStatusList_TYPE * SMI_PortStatusList=(PortStatusList_TYPE *)malloc(sizeof(PortStatusList_TYPE));

    SMI_PortStatusList->ArgBlockID=0x9000;
    SMI_PortStatusList->PortStatusInfo=0x04; //OPERATE
    SMI_PortStatusList->PortQualityInfo=0x00;// invalid
    SMI_PortStatusList->RevisionID=RevisionID[Port]; //RevisionID
    SMI_PortStatusList->TransmissionRete=SM_COM_Speed[Port]; //Transmission rate
    SMI_PortStatusList->VendorID=VendorID;
    SMI_PortStatusList->DeviceID=DeviceID;
    SMI_PortStatusList->MasterCycleTime=CfgCycleTime[Port];

     Insert_SMI_Object_To_Result_FIFO(0x0000,Port,sizeof(SMI_PortStatusList[Port]),(void *)&SMI_PortStatusList[Port]);

}


void CM_T9(uint8_t Port){
     Event_DS_Delete(Port);   

     SM_SetPortConfig_Arg_TYPE SM_Arg;
    //解析SMI的ConfigList,得到SM_SetConfig部分参数
    Parase_PortConfigList(Port,&SM_Arg,&SMI_PortConfigList[Port]);
     
  
    //调用SM_SetPortConfig服务
    Service_SM_SetPortConfig_req(SM_Arg);


     PortStatusList_TYPE * SMI_PortStatusList=(PortStatusList_TYPE *)malloc(sizeof(PortStatusList_TYPE));

    SMI_PortStatusList->ArgBlockID=0x9000;
    SMI_PortStatusList->PortStatusInfo=0x05; //DI_C/Q
    SMI_PortStatusList->PortQualityInfo=0x00;// invalid
    SMI_PortStatusList->RevisionID=0; //RevisionID
    SMI_PortStatusList->TransmissionRete=0; //Transmission rate
    SMI_PortStatusList->VendorID=0;
    SMI_PortStatusList->DeviceID=0;
    SMI_PortStatusList->MasterCycleTime=0;

     Insert_SMI_Object_To_Result_FIFO(0x0000,Port,sizeof(SMI_PortStatusList[Port]),(void *)&SMI_PortStatusList[Port]);

}


void CM_T10(uint8_t Port){
       Event_DS_Delete(Port);   

     SM_SetPortConfig_Arg_TYPE SM_Arg;
    //解析SMI的ConfigList,得到SM_SetConfig部分参数
    Parase_PortConfigList(Port,&SM_Arg,&SMI_PortConfigList[Port]);
     
  
    //调用SM_SetPortConfig服务
    Service_SM_SetPortConfig_req(SM_Arg);


     PortStatusList_TYPE * SMI_PortStatusList=(PortStatusList_TYPE *)malloc(sizeof(PortStatusList_TYPE));

    SMI_PortStatusList->ArgBlockID=0x9000;
    SMI_PortStatusList->PortStatusInfo=0x06; //DI_C/Q
    SMI_PortStatusList->PortQualityInfo=0x00;// invalid
    SMI_PortStatusList->RevisionID=0; //RevisionID
    SMI_PortStatusList->TransmissionRete=0; //Transmission rate
    SMI_PortStatusList->VendorID=0;
    SMI_PortStatusList->DeviceID=0;
    SMI_PortStatusList->MasterCycleTime=0;

     Insert_SMI_Object_To_Result_FIFO(0x0000,Port,sizeof(SMI_PortStatusList[Port]),(void *)&SMI_PortStatusList[Port]);

}

void CM_T11(uint8_t Port){
    Event_DS_Delete(Port);   

     SM_SetPortConfig_Arg_TYPE SM_Arg;
    //解析SMI的ConfigList,得到SM_SetConfig部分参数
    Parase_PortConfigList(Port,&SM_Arg,&SMI_PortConfigList[Port]);
     
  
    //调用SM_SetPortConfig服务
    Service_SM_SetPortConfig_req(SM_Arg);


     PortStatusList_TYPE * SMI_PortStatusList=(PortStatusList_TYPE *)malloc(sizeof(PortStatusList_TYPE));

    SMI_PortStatusList->ArgBlockID=0x9000;
    SMI_PortStatusList->PortStatusInfo=0x01; //DEACTIVATED
    SMI_PortStatusList->PortQualityInfo=0x00;// invalid
    SMI_PortStatusList->RevisionID=0; //RevisionID
    SMI_PortStatusList->TransmissionRete=0; //Transmission rate
    SMI_PortStatusList->VendorID=0;
    SMI_PortStatusList->DeviceID=0;
    SMI_PortStatusList->MasterCycleTime=0;

     Insert_SMI_Object_To_Result_FIFO(0x0000,Port,sizeof(SMI_PortStatusList[Port]),(void *)&SMI_PortStatusList[Port]);

}


void CM_T14(uint8_t Port){
    SM_SetPortConfig_Arg_TYPE SM_Arg;
    //解析SMI的ConfigList,得到SM_SetConfig部分参数
    Parase_PortConfigList(Port,&SM_Arg,&SMI_PortConfigList[Port]);
    SM_Arg.TargetMode=SM_CFGCOM;
  
    //调用SM_SetPortConfig服务
    Service_SM_SetPortConfig_req(SM_Arg);
 
}

void CM_T16(uint8_t Port){
    Event_DS_Delete(Port);   

    SM_SetPortConfig_Arg_TYPE SM_Arg;
    //解析SMI的ConfigList,得到SM_SetConfig部分参数
    Parase_PortConfigList(Port,&SM_Arg,&SMI_PortConfigList[Port]);
     
  
    //调用SM_SetPortConfig服务
    Service_SM_SetPortConfig_req(SM_Arg);
    SM_Arg.TargetMode=SM_INACTIVE;

     PortStatusList_TYPE * SMI_PortStatusList=(PortStatusList_TYPE *)malloc(sizeof(PortStatusList_TYPE));

    SMI_PortStatusList->ArgBlockID=0x9000;
    SMI_PortStatusList->PortStatusInfo=0x01; //DEACTIVATED
    SMI_PortStatusList->PortQualityInfo=0x00;// invalid
    SMI_PortStatusList->RevisionID=0; //RevisionID
    SMI_PortStatusList->TransmissionRete=0; //Transmission rate
    SMI_PortStatusList->VendorID=0;
    SMI_PortStatusList->DeviceID=0;
    SMI_PortStatusList->MasterCycleTime=0;

     Insert_SMI_Object_To_Result_FIFO(0x0000,Port,sizeof(SMI_PortStatusList[Port]),(void *)&SMI_PortStatusList[Port]);

}


//******************Event**********************/
void Event_CM_PortConfigList_changed(uint8_t Port){
       CM_STATE[Port]=CM_CheckPortMode_0;
       Action_do_ModeCheck(Port);
    
}

void Event_CM_DEACTIVED(uint8_t Port){
   if(CM_STATE[Port]==CM_CheckPortMode_0){
       CM_STATE[Port]=CM_Port_Deactived_8;
       CM_T11(Port);
   }
}

void Event_CM_DI_CQ(uint8_t Port){
    if(CM_STATE[Port]==CM_CheckPortMode_0){
        CM_STATE[Port]=CM_Port_DIDO_6;
        CM_T9(Port);
    }

}


void Event_CM_DO_CQ(uint8_t Port){
   if(CM_STATE[Port]==CM_CheckPortMode_0){
        CM_STATE[Port]=CM_Port_DIDO_6;
        CM_T10(Port);
    }
  
  
}

void Event_CM_IOL_AUTOSTART(uint8_t Port){
    if(CM_STATE[Port]==CM_CheckPortMode_0){
        CM_STATE[Port]=CM_SM_Startup_1;
        CM_T2(Port);
    }
}

void Event_CM_IOL_MANUAL(uint8_t Port){
     if(CM_STATE[Port]==CM_CheckPortMode_0){
        CM_STATE[Port]=CM_SM_Startup_1;
        CM_T1(Port);
    }
}

void Event_CM_Unknown(uint8_t Port){
    if(CM_STATE[Port]==CM_CheckPortMode_0){
        CM_STATE[Port]=CM_Port_Deactived_8;
        CM_T16(Port);
    }
}


void Event_SM_PortMode_COMREADY(uint8_t Port){
    if(CM_STATE[Port]==CM_SM_Startup_1){
        CM_STATE[Port]=CM_DS_ParamManager_2;
        CM_T3(Port);
    }
}
void Event_SM_PortMode_xFAULT(uint8_t Port){
    if(CM_STATE[Port]==CM_SM_Startup_1){
        CM_STATE[Port]=CM_PortFault_3;
        CM_T4(Port);
    }

} 
 
void Event_SM_PortMode_COMLOST(uint8_t Port){
    Action_do_ModeCheck(Port);
}
   
void Event_SM_PortMode_OPERATE(uint8_t Port){
   if(CM_STATE[Port]==CM_WaitingOnOperate_4){
       CM_STATE[Port]=CM_Port_Active_5;
       CM_T7(Port);
   }
}

void Event_DS_Ready(uint8_t Port){
    if(CM_STATE[Port]==CM_DS_ParamManager_2){
        CM_STATE[Port]=CM_WaitingOnOperate_4;
        CM_T5(Port);
    }
}


void Event_DS_Fault(uint8_t Port){
    if(CM_STATE[Port]==CM_SM_Startup_1){
        CM_STATE[Port]=CM_PortFault_3;
        CM_T6(Port);
    }
}


void Event_DS_CHange(uint8_t Port){
   if(CM_STATE[Port]==CM_PortFault_3||CM_STATE[Port]==CM_DS_ParamManager_2||CM_STATE[Port]==CM_WaitingOnOperate_4||CM_STATE[Port]==CM_Port_Active_5){
        CM_STATE[Port]=CM_SM_Startup_1;
        CM_T14(Port);
   }
}

/******************辅助函数 ******************/
//SM_Arg参数逐步完善，不是一次完成
void Parase_PortConfigList(uint8_t Port,SM_SetPortConfig_Arg_TYPE * SM_Arg, PortConfigList_TYPE * ConfigList){
   //解析PortMode
   if(ConfigList->PortMode==0x00){ //PortMode=DEACTVATED
        SM_Arg->TargetMode=SM_INACTIVE;
        
   }
   else if(ConfigList->PortMode==0x01){ //PortMode==IOL_MANUAL
        SM_Arg->TargetMode=SM_CFGCOM;
   }
   else if(ConfigList->PortMode==0x02){ //PortMode==IOL_AUTOSTART
         SM_Arg->TargetMode=SM_AUTOCOM;
   }
   else if(ConfigList->PortMode==0x03){ //PortMode==DI_C/Q
         SM_Arg->TargetMode=SM_DI;
   }
   else if(ConfigList->PortMode==0x04){ //PortMode==DO_C/Q
       SM_Arg->TargetMode=SM_DO;
   }else{
       SM_Arg->TargetMode=SM_INACTIVE;
   }
   

   // 解析校验等级
   if(ConfigList->Validation_and_Backup=0x00){ //Validation=No Device check
        SM_Arg->InspectionLevel=SM_NO_CHECK;
        DS_Enable_Flag[Port]=False;
        DS_UploadEnable_Flag[Port]=False;
        DS_DownLoad_Flag[Port]=False;
        
        Event_DS_Cleared_or_Disabled(Port);

   }
   else if(ConfigList->Validation_and_Backup==0x01){ //Validation== Type Compatiblie Device V1.0
       SM_Arg->InspectionLevel=SM_TYPE_COMP;
        DS_Enable_Flag[Port]=False;
        DS_UploadEnable_Flag[Port]=False;
        DS_DownLoad_Flag[Port]=False;
        
        Event_DS_Cleared_or_Disabled(Port);

   }
   else if(ConfigList->Validation_and_Backup==0x02){
       SM_Arg->InspectionLevel=SM_TYPE_COMP;
        DS_Enable_Flag[Port]=False;
        DS_UploadEnable_Flag[Port]=False;
        DS_DownLoad_Flag[Port]=False;
         
          Event_DS_Cleared_or_Disabled(Port);
     
   }
   else if(ConfigList->Validation_and_Backup==0x03){
       SM_Arg->InspectionLevel=SM_TYPE_COMP;
       DS_Enable_Flag[Port]=True;
       DS_UploadEnable_Flag[Port]=True;
       DS_DownLoad_Flag[Port]=True;

       Event_DS_Enabled(Port);
   }
   else if(ConfigList->Validation_and_Backup==0x04){
       SM_Arg->InspectionLevel=SM_TYPE_COMP;
       DS_Enable_Flag[Port]=True;
       DS_UploadEnable_Flag[Port]=False;
       DS_DownLoad_Flag[Port]=True;
       
        Event_DS_Enabled(Port);


   }else{  //如果都不符合。则按照 Type compatible Device V1.1 Restore进行
        SM_Arg->InspectionLevel=SM_TYPE_COMP;
       DS_Enable_Flag[Port]=True;
       DS_UploadEnable_Flag[Port]=False;
       DS_DownLoad_Flag[Port]=True;

       Event_DS_Enabled(Port); 
   }

   SM_Arg->Port=Port;
   SM_Arg->ConfiguredCycleTime=ConfigList->PortCycleTime;
   SM_Arg->CVID=ConfigList->VendorID;
   SM_Arg->CDID=ConfigList->DeviceID;
   

}



void Action_do_ModeCheck(uint8_t Port){
    Parase_PortConfigList(,&SMI_PortConfigList);
    if(SMI_PortConfigList[Port].PortMode==0){ //DEACTIVEAED
        Event_CM_DEACTIVED(Port);
    }
    else if(SMI_PortConfigList[Port].PortMode==3){  //DI_CQ
        Event_CM_DI_CQ(Port);
    }
    else if(SMI_PortConfigList[Port].PortMode== 4 ){ //DO_CQ
        Event_CM_DO_CQ(Port);
    }
    else if(SMI_PortConfigList[Port].PortMode==2  ){ //IOL_AUTOCOM
        Event_CM_IOL_AUTOSTART(Port);
    }
    else if(SMI_PortConfigList[Port].PortMode==1  ){ //IOL_MANUAL
        Event_CM_IOL_MANUAL(Port);
    }else
    {
        Event_CM_Unknown(Port);
        return;        
     }
    
}
